package com.informix.stream.api.records;

import com.informix.stream.api.IfmxStreamRecord;
import com.informix.stream.common.enums.IfmxStreamRecordType;
import com.informix.stream.common.exception.IfxStreamException;

public abstract class IfxCDCRecord implements IfmxStreamRecord {
  protected long sequence = -1L;
  protected int transaction = -1;
  protected String label;
  protected final IfmxStreamRecordType type;

  public IfxCDCRecord(IfmxStreamRecordType type) {
    this.type = type;
  }

  public boolean isWrapperFor(IfmxStreamRecordType aType) {
    return aType.equals(this.getType());
  }

  public boolean isWrapperFor(Class<?> iface) {
    return iface.isInstance(this);
  }

  public <T> T unwrap(Class<T> iface) throws IfxStreamException {
    if (iface.isInstance(this)) {
      return (T) this;
    } else {
      throw new IfxStreamException(
          "Invalid cast from ["
              + this.getClass().getCanonicalName()
              + "] to ["
              + iface.getClass().getCanonicalName()
              + "]");
    }
  }

  @Override
  public long getSequenceId() {
    return this.sequence;
  }

  @Override
  public int getTransactionId() {
    return this.transaction;
  }

  @Override
  public String getLabel() {
    return this.label;
  }

  @Override
  public IfmxStreamRecordType getType() {
    return this.type;
  }

  @Override
  public boolean hasOperationData() {
    return false;
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("[" + this.getType() + "]");
    if (this.transaction != -1) {
      sb.append(" Transaction ID [" + this.transaction + "]");
    }

    if (this.sequence != -1L) {
      sb.append(" Sequence ID [" + this.sequence + "]");
    }

    if (this.label != null) {
      sb.append(" Label [" + this.label + "]");
    }

    return sb.toString();
  }
}
